---
title: "Log4Shell Update: Second log4j Vulnerability Published (CVE-2021-44228 + CVE-2021-45046)"
description: A quick update on the situation now that a new log4j CVE has been created and patched in 2.16.0. We've done research and these are our findings.
slug: log4j-zero-day-update-on-cve-2021-45046
date: 2021-12-19
image: https://www.lunasec.io/docs/img/log4shell-logo.png
keywords: [log4shell, log4j, log4j2, rce, java, zero-day, mitigation]
tags: [zero-day, security, data-security, guides, log4shell]
authors: [free, chris, forrest]

---
<!--
  ~ Copyright by LunaSec (owned by Refinery Labs, Inc)
  ~
  ~ Licensed under the Creative Commons Attribution-ShareAlike 4.0 International
  ~ (the "License"); you may not use this file except in compliance with the
  ~ License. You may obtain a copy of the License at
  ~
  ~ https://creativecommons.org/licenses/by-sa/4.0/legalcode
  ~
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  ~
-->

![Log4Shell Logo](https://www.lunasec.io/docs/img/log4shell-logo.png)

_Originally Posted @ December 14th & Last Updated @ December 19th, 3:37pm PST_

**Just trying to fix this? Please read our dedicated
[Mitigation Guide](https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide).**

After the log4j maintainers released version `2.15.0` to address the
[Log4Shell vulnerability](https://www.lunasec.io/docs/blog/log4j-zero-day/), an additional attack vector
was identified and reported in [CVE-2021-45046](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046).

Our research into this shows that this new CVE invalidates previous mitigations used to protect versions
`2.7.0 <= Apache log4j <= 2.14.1` from Log4Shell in some cases.

## Conditions for the vulnerability

You may still be vulnerable to Log4Shell (RCE), if you only enabled the `formatMsgNoLookups` flag or set
`%m{nolookups}` when you also set data in the `ThreadContext` with attacker controlled data. In this case, you must
upgrade to `>= 2.15.0`, or else you will still be vulnerable to RCE.

:::note For version `2.15.0`
** Update ** There has been a limited RCE discovered in `2.15.0`, and the [severity has been upgraded](https://www.lunasec.io/docs/blog/log4j-zero-day-severity-of-cve-2021-45046-increased/)
from `3.7 -> 9.0`.

We found that the DOS outlined in the CVE was not actually impactful because it did not consume resources
during our testing (see [below](#notes-on-the-denial-of-service-in-2.15.0)).

Our reproduction could be incomplete however, so we continue to recommend that you upgrade to `2.17.0` in the event that a better
exploit is found to abuse this attack vector.
:::

<!--truncate-->

## The new CVE is difficult to understand

The mention of possible RCE is unfortunately missing from the published CVE. In the CVE
it only mentions a possible "Denial-of-Service" attack for versions prior to `2.15.0` and `2.16.0`.

Because of these findings, we recommend that everybody using log4j immediately upgrades to `2.17.0` or later, or manually
patches their log4j classes (for details, see our
[Mitigation Guide](https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide)). Please read the rest of this post for context about
our research.

## Context on CVE-2021-45046

The new CVE states:

> It was found that the fix to address CVE-2021-44228 in Apache Log4j 2.15.0 was incomplete in certain non-default configurations.

We found this report concerning as it states that one of the recommended temporary mitigations for versions
`2.7.0 <= Apache log4j <= 2.14.1`
might not protect against this CVE. Further:

> Note that previous mitigations involving configuration such as to set the system property `log4j2.formatMsgNoLookups` to `true` do NOT mitigate this specific vulnerability.

It was not readily apparently from reading this CVE what specifically was affected, or how this vulnerability is actually
triggered. That's why we actually tested this ourselves to figure out what the impact was.

## Testing previous mitigations

Fortunately the community has been hard at work reacting to these updates. A fork of
[christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) has
[added some changes](https://github.com/kmindi/log4shell-vulnerable-app/commit/e539f7e9a0c81e2c580d63caff5f4eae14033f19)
to demonstrate the specific scenario in which this newly found CVE could affect an application.

In these changes, the previously discovered mitigation was included:

```bash
# Add environment variable as the currently official workaround for vulnerable versions of log4j2 (e.g. 2.14.1)
ENV LOG4J_FORMAT_MSG_NO_LOOKUPS true
```

And the Log4j2 properties config includes a custom layout pattern:

```bash
# ...
# vulnerable in 2.14.1 even with ENV LOG4J_FORMAT_MSG_NO_LOOKUPS true
appender.console.layout.pattern = ${ctx:apiversion} - %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# ...
```

Now, instead of directly logging the attacker controlled input as with the previous vulnerability like this:

```ts
@GetMapping("/")
public String index(@RequestHeader("X-Api-Version") String apiVersion) {
    logger.info("Received a request for API version " + apiVersion);
    return "Hello, world!";
}
```

In the layout pattern above, the `${ctx:apiversion}` format string refers to a `ThreadContext` value named `apiversion`.
In order to trigger the vulnerability, there needs to be code which lets the attacker influence the `apiversion` value.
The below handler demonstrates what this might look like in code:

```ts
@GetMapping("/")
public String index(@RequestHeader("X-Api-Version") String apiVersion) {

    // Add user controlled input to threadcontext;
    // Used in log via ${ctx:apiversion}
    ThreadContext.put("apiversion", apiVersion);

    // Notice how these changes remove apiVersion from directly being logged
    logger.info("Received a request for API version");
    return "Hello, world!";
}
```

:::info Vulnerable App Log4j version

This vulnerable application was running with Log4j version `2.14.1`, which is still vulnerable to the RCE even
_before_ the `LOG4J_FORMAT_MSG_NO_LOOKUPS` mitigation.

:::

## Our Findings

### Issues when using `log4j2.formatMsgNoLookups` (>=2.10.0)

Running this vulnerable server and exploiting the vulnerability with our [log4shell CLI tool](https://github.com/lunasec-io/lunasec/tree/master/tools/log4shell),
we observed that RCE was still possible in versions `2.10.0 <= Apache log4j < 2.14.1`:

<a href="https://www.lunasec.io/docs/img/log4shell-CVE-2021-45046-exploitation-with-mitigation.png" target="_blank" rel="noopener">
  <img src="https://www.lunasec.io/docs/img/log4shell-CVE-2021-45046-exploitation-with-mitigation.png" alt="Log4j RCE on log4j 2.14.1 with mitigation" />
</a>

The server is still vulnerable even with `log4j2.formatMsgNoLookups` enabled because the Pattern Layout has been modified
to include a reference to a Thread Context value. It appears that referencing Thread Context values in this way bypasses
the logic for disabling JNDI lookups when formatting a message. The [CVE report](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046)
outlines this as well as the other types of affected format strings:

> This could allow attackers with control over Thread Context Map (MDC) input data when the logging configuration uses
a non-default Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern
(%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern.

We were not able to achieve RCE when using `%X, %mdc, or %MDC`, however we still do not consider these as safe to include
when running a Log4j version `< 2.16.0`. To understand more about the Log4j Thread Context map, please refer to the [docs](https://logging.apache.org/log4j/2.x/manual/thread-context.html).

If you have previously used `LOG4J_FORMAT_MSG_NO_LOOKUPS` to mitigate the log4shell vulnerability, in certain conditions
this will not be sufficient to protect your code from RCE. Refer to our [mitigation guide](https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide)
for additional steps you can take to remediate the impact of Log4Shell.

### Setting `%m{nolookups}` is still vulnerable (>=2.7.0)

We continue to recommend _not_ using `%m{nolookups}`, as explained in our [mitigation guide](https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide), since we have
proven the vulnerability is still exploitable with a Pattern Layout such as:

```
appender.console.layout.pattern = ${ctx:apiversion} - %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m{nolookups}%n
```

`%m{nolookups}` will only apply to the content being logged in the call to `logger.info()`, and will not apply to the
resolving of `${ctx:apiversion}` which will contain our payload.

### Notes on the Denial-of-Service in 2.15.0

** Update ** There has been a limited RCE discovered in `2.15.0`, and the [severity has been upgraded](https://www.lunasec.io/docs/blog/log4j-zero-day-severity-of-cve-2021-45046-increased/)
from `3.7 -> 9.0`.

The less impactful part of this CVE, if you have updated your Log4j version to `2.15.0`, is that there is a limited
denial of service (DOS), possible under certain circumstances. See the below screenshot:

<a href="https://www.lunasec.io/docs/img/log4shell-CVE-2021-45046-dos-with-mitigation.png" target="_blank" rel="noopener">
  <img src="https://www.lunasec.io/docs/img/log4shell-CVE-2021-45046-dos-with-mitigation.png" alt="Log4j DOS on log4j 2.15.0 with mitigation" />
</a>

However, in our testing we did not find this DOS to be resource consuming, as it seemed that the infinite loop created by recursively
resolving `${ctx:apiversion}` was identified by the program and errored out.

Log4j `2.16.0` completely mitigates this issue by removing support for message lookup patterns and disabling JNDI functionality by default. `2.16.0` has its own issues, however, so please upgrade to `2.17.0` or newer.
## Stay Updated

Please follow us on [Twitter](https://twitter.com/LunaSecIO) or add yourself to our mailing list below, and we'll
update you when we publish new findings.

If this post helped you, please share it with others.

import ContactForm from '../src/components/ContactForm.jsx'

<ContactForm/>

## Additional Information

We have published a series of posts about Log4Shell on our blog that you might be interested in:
- **[Mitigation Guide](https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide/)**
- **[Original Log4Shell Announcement](https://www.lunasec.io/docs/blog/log4j-zero-day/)**
- **[Part 1: Log4Shell Live Patch (Background Context)](https://www.lunasec.io/docs/blog/log4shell-live-patch/)**
- **[Part 2: Log4Shell Live Patch (Technical Deep-Dive)](https://www.lunasec.io/docs/blog/log4shell-live-patch-technical/)**

### Limited Offer: Free Security Assistance

We're also currently offering a free 30-minute consultation with one of our Security Engineers. If you're interested,
please [book some time with us here](https://lunasec.youcanbook.me/).

## Updates

:::info
We're continuously keeping this post up-to-date as new information comes out. If you have any questions, or you're
confused about our advice, please [file an Issue](https://github.com/lunasec-io/lunasec/issues) on GitHub.

If you would like to contribute, or notice any errors, this post is an Open Source Markdown file on
[GitHub](https://github.com/lunasec-io/lunasec/blob/master/docs/blog/2021-12-14-log4j-zero-day-update-on-CVE-2021-45046.mdx).
:::

1. Updated 12/15/21: Updated "Conditions for the Vulnerability" section from "upgrade to `2.16.0`" to "upgrade to `>= 2.15.0`", see [this GitHub issue](https://github.com/lunasec-io/lunasec/issues/316).
2. Updated 12/15/21: Updated all instances of `noFormatMsgLookup` to be the correct `formatMsgNoLookups`, see [this GitHub issue](https://github.com/lunasec-io/lunasec/issues/317).
3. Updated 12/16/21: Added links to other blog posts.
4. Updated 12/18/21: Updated note about 2.15.0 that RCE has been found.
5. Updated 12/19/21: Updated advice about 2.16.0 to recommend 2.17.0 now.
